package entutils

import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"text/template"
	"time"
)

type Template struct {
	template *template.Template
	out      string
}

func NewTemplate(template *template.Template) *Template {
	return &Template{template: template}
}
func (t *Template) Execute(baseDir string, data any) error {
	out, err := t.renderOutPath(baseDir, data)
	if err != nil {
		return fmt.Errorf("renderOutPath %w", err)
	}
	t.out = out
	if isExist(out) {
		return nil
	}
	err = t.renderFile(data, out)
	if err != nil {
		return fmt.Errorf("renderFile %w", err)
	}
	return nil
}
func (t *Template) renderFile(data any, out string) error {
	var buf bytes.Buffer
	if err := t.template.Execute(&buf, data); err != nil {
		return fmt.Errorf("template execute %s %w", out, err)
	}
	if err := os.WriteFile(out, buf.Bytes(), 0755); err != nil {
		return fmt.Errorf("os.WriteFile %s %w", out, err)
	}
	return nil
}
func (t *Template) renderOutPath(baseDir string, data any) (string, error) {
	var (
		builder          strings.Builder
		outTemplate, err = template.New(time.Now().String()).Parse(t.template.Name())
	)
	if err != nil {
		return "", fmt.Errorf("outTemplate.Parse %s %w", t.template.Name(), err)
	}

	err = outTemplate.Execute(&builder, data)
	if err != nil {
		return "", fmt.Errorf("outTemplate.Execute %s %w", t.template.Name(), err)
	}

	return filepath.Join(baseDir, builder.String()), nil
}
func isExist(p string) bool {
	_, err := os.Stat(p)
	return err == nil
}
